/*********************************************************************************
 *      Copyright:  (C) 2023 LXC
 *                  All rights reserved.
 *
 *       Filename:  main.c
 *    Description:  This file : client
 *                 
 *        Version:  1.0.0(08/05/23)
 *         Author:  Lin XinCheng <1481155734@qq.com>
 *      ChangeLog:  1, Release initial version on "08/05/23 16:48:22"
 *                 
 ********************************************************************************/
#include <time.h>
#include <stdio.h>
#include <netdb.h>
#include <errno.h>
#include <fcntl.h>
#include <getopt.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/stat.h>
#include <arpa/inet.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>

#include "get_temp.h"
#include "get_time.h"
#include "socket.h"
#include "sqlite.h"
#include "logger.h"
#include "pack_data.h"

#define LOG_LEVEL LOG_ERROR

int print_usage(char *progname);

int main(int argc, char **argv)
{
	char				*hostname = NULL;							
	int			 		 port = 0;									
	char				*device_id = "001";							
	int			 	 	 interval_sec = 1800;						
	char				*db_name = "1.db";					
	char				*log_filename = "stdout";					
	int					 daemon_flag = 0;							
	int					 sample_flag = 0;							
	time_t				 pretime = 0;								
	time_t				 nowtime = 0;								
	char			 	 data[128] = {0};							
	char			 	 query_data[128] = {0};						
	socket_t			 sock;										
	packet_t			 pack;										
	int			 		 ch = -1;									
	struct option		 opts[] =							 
	{
		{"ipaddr", required_argument, NULL, 'i'},
		{"port", required_argument, NULL, 'p'},
		{"serial", required_argument, NULL, 's'},
		{"interval", required_argument, NULL, 't'},
		{"help", no_argument, NULL, 'h'},
		{NULL, 0, NULL, 0}
	};

	/*命令行参数解析 */
	while( (ch = getopt_long(argc, argv, "i:p:s:t:h", opts, NULL)) != -1 )
	{
		switch( ch )
		{
			case 'i':
				hostname = optarg; 			/* 服务器ip/主机名/域名 */
				break;
			case 'p':
				port = atoi(optarg); 		/* 服务器端口号 */
				break;
			case 's':
				device_id = optarg; 		/* 设备id */
				break;
			case 't':
				interval_sec = atoi(optarg);/* 采样时间间隔 */
				break;
			case 'h': 
				print_usage(argv[0]); 		/* 打印帮助信息 */
				return 0;
		}
	}

	if( (!hostname) || (!port) )				/* 判断输入参数是否合法 */
	{											
		print_usage(argv[0]);					/* 打印帮助信息 */
		return 0;
	}
	printf("socket[%s:%d]\n", hostname, port);

	if ( daemon_flag )									/* 判断是否要后台运行 */
	{											
		daemon(1, 0);									
		if ( 0 == (strcmp(log_filename, "stdout")) )	
		{			
            /* 指定一个默认日志文件client.log */									
			log_filename = "client.log";			
		}
	}

	logger_init(log_filename, LOG_LEVEL);		/* 设置日志文件名和日志记录级别 */
	
	socket_init(&sock, hostname, port);			/* 初始化socket */

	if ( 0 < db_init(db_name) )     	      /* 初始化数据库 */
	{										
		return -1;
	}

	pretime = 0;
	while( 1 )
	{
        //未采集 
		sample_flag = 0;												
		time(&nowtime);													
		if ( (nowtime - pretime) >= interval_sec )/* 判断是否到采集时间 */
		{																
			memset(&pack, 0, sizeof(pack));
			strncpy(pack.dev_id, device_id, sizeof(pack.dev_id));		/* 设备id */
			get_time(pack.dev_time);									/* 获取当前日期时间 */
			get_temp(&pack.dev_temp);									/* 采集温度 */

			sample_flag = 1;											
			pretime = nowtime;										
		}
        //判断连接
		socket_diag(&sock);				

		//连接失败
		if ( !sock.connected )			
		{
			socket_connect(&sock);		
		}
		if ( !sock.connected )			
		{
			if ( 1 == sample_flag )		
				db_insert(&pack);//将采集的数据插入数据库中
			}
			continue;
		}

		//连接成功
		if ( 1 == sample_flag )	
		{					
            //将采集的数据从pack打包到data							
			pack_data(&pack, data, strlen(data)); 				
			//发送数据 
            if ( socket_write(&sock, data, strlen(data)) < 0 )	
			{													
				db_insert(&pack);								
				socket_close(&sock);							
			}
		}

		if ( 0 == db_query(&pack) )								/* 查询数据库是否有数据 */ 
		{														
			pack_data(&pack, data, strlen(data));				/* 将查询到的数据pack打包到data中 */
			//发送数据data
            if ( socket_write(&sock, data, strlen(data)) < 0 )	
			{													
				socket_close(&sock);							
			}
			db_delete();										
		}

	}

    //关闭socket 
	socket_close(&sock);										

    //关闭数据库 
	db_close();													

	//关闭日志 
	logger_destroy();
	return 0;
}

int print_usage(char *progname)
{
	if ( NULL == progname )
	{
		return -1;
		LOGGER_ERROR("NULL pointer");
	}
	printf("%s usage: \n", progname);
	printf("-i(--ipaddr): sepcify server IP address or hostname or domain name.\n");
	printf("-p(--port): sepcify server port.\n");
	printf("-s(--serial): sepcify device serial number.\n");
	printf("-t(--time):sepcify sampling interval.\n");
	printf("-h(--help): print help informatiom.\n");
	printf("\n");
	return 0;
}
